Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add EgressRule to NetworkPolicy #51351

Merged
merged 3 commits into from
Sep 6, 2017

Conversation

cmluciano
Copy link

@cmluciano cmluciano commented Aug 25, 2017

What this PR does / why we need it:
Add EgressRule to NetworkPolicy

Which issue this PR fixes: fixes #50453

Special notes for your reviewer:

  • Please take a look at the comments for the various types. I tried to mimic some of the language used in the Ingress comments, but I may have mangled some sentences.
  • Let me know if I should add some test cases for validation. I have 2-3, and did not think it was necessary to replicate each case already covered in ingress.

Release note:

Add egress policies to NetworkPolicy

@cmluciano cmluciano added the sig/network Categorizes an issue or PR as relevant to SIG Network. label Aug 25, 2017
@cmluciano cmluciano added this to the v1.8 milestone Aug 25, 2017
@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Aug 25, 2017
@k8s-github-robot k8s-github-robot added kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API release-note Denotes a PR that will be considered when it comes time to generate release notes. labels Aug 25, 2017
@@ -55,6 +55,16 @@ type NetworkPolicySpec struct {
// solely to ensure that the pods it selects are isolated by default)
// +optional
Ingress []NetworkPolicyIngressRule

// List of egress rules to be applied to the selected pods. Outgoing traffic is
//allowed unbounded if there are no NetworkPolicies selecting the pod
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing space after "//", and the word "unbounded" doesn't seem necessary, and also we need to add the thing discussed in https://groups.google.com/d/msg/kubernetes-sig-network/nWyAL-8vKV8/DDRZ9Jx8BwAJ so that all pods with ingress rules don't suddenly become default-deny to egress

// List of egress rules to be applied to the selected pods. Outgoing traffic is
//allowed unbounded if there are no NetworkPolicies selecting the pod
// (and cluster policy otherwise allows the traffic), OR if the traffic source is
// the pod's local node, OR if the traffic matches at least one egress rule
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"if the traffic source is the pod's local node" is meaningless here. You might have meant to change it to "if the traffic destination is the pod's local node", but I don't think we need that exception here. (It exists in ingress rules to make sure that the kubelet can do health checks on pods.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree we do not need the excption, unless someone can say exactly why we need it.

// the pod's local node, OR if the traffic matches at least one egress rule
// across all of the NetworkPolicy objects whose podSelector matches the pod. If
// this field is empty then this NetworkPolicy does not limit any outgoing traffic
// (and serves solely to ensure that the pods it selects are isolated by default)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does not allow any outgoing traffic

@@ -77,6 +87,26 @@ type NetworkPolicyIngressRule struct {
From []NetworkPolicyPeer
}

// NetworkPolicyEgressRule describes a particular set of traffic that pods can egress to
// matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"NetworkPolicyEgressRule describes a particular set of traffic that is allowed out of pods matched by a NetworkPolicySpec's podSelector."

// matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to.
type NetworkPolicyEgressRule struct {
// List of destination ports for outgoing traffic.
//Each item in this list is combined using a logical OR. If this field is
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(missing space)

//Each item in this list is combined using a logical OR. If this field is
// empty or missing, this rule matches all ports (traffic not restricted by port).
// If this field is present and contains at least one item, then this rule does note
// constrain outgoing traffic.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"If this field is present and contains at least one item, then this rule allows traffic only if the traffic matches at least one port in the list". (Just copied from NetworkPolicyIngressRule.Ports)

// source). If this field is present and contains at least on item, this rule
// allows traffic only if the traffic matches at least one item in the from list.
// +optional
To []NetworkPolicyPeer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// List of sources destinations for outgoing traffic of pods selected for this rule.
// Items in this list are combined using a logical OR operation. If this field is
// empty or missing, this rule matches all sources destinations (traffic not restricted by
// source destination). If this field is present and contains at least on one item, this rule
// allows traffic only if the traffic matches at least one item in the from to list.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the to list. -> in the To list.

// Validate egress rules
for i, egress := range spec.Egress {
egressPath := fldPath.Child("egress").Index(i)
for i, port := range egress.Ports {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should split out ValidateNetworkPolicyPort and ValidateNetworkPolicyPeer functions to share between ingress and egress validation

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(You "+1"ed this but then didn't actually do it.)

Copy link
Member

@thockin thockin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good overall

// List of egress rules to be applied to the selected pods. Outgoing traffic is
//allowed unbounded if there are no NetworkPolicies selecting the pod
// (and cluster policy otherwise allows the traffic), OR if the traffic source is
// the pod's local node, OR if the traffic matches at least one egress rule
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree we do not need the excption, unless someone can say exactly why we need it.

// this field is empty then this NetworkPolicy does not limit any outgoing traffic
// (and serves solely to ensure that the pods it selects are isolated by default)
// +optional
Egress []NetworkPolicyEgressRule
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a comment indicating 'beta' or 'alpha' ? @lavalamp since machinery team seems to want people to just use fields rather than annotations, shouldn't the generated docs at least say "beta" ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't we decide we need a field to discriminate whether this policy was applying ingress vs egress?

Copy link
Author

@cmluciano cmluciano Aug 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes @danwinship mentioned the additional PolicyType above. Adding now.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it should be beta, but I was not sure if the format was supposed to be similar to the feature gate note or not.

// owner: @cmluciano
// beta: v1.8

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've noticed this doesn't mention local node. What's the behavior for if the traffic destination is the pod's local node?

// source). If this field is present and contains at least on item, this rule
// allows traffic only if the traffic matches at least one item in the from list.
// +optional
To []NetworkPolicyPeer `json:"to,omitempty" protobuf:"bytes,2,rep,name=to"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

port/to is kind of awkward in this direction. ingress.ports and ingress.from makes sense. I'm not sure I have a better answer off the top of my head, and breaking symmetry would be bad, but ... better ideas?

Copy link
Author

@cmluciano cmluciano Aug 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does Out sound any better than To?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for ports/out

@thockin
Copy link
Member

thockin commented Aug 26, 2017

Are we declaring the beta?

@cmluciano
Copy link
Author

@thockin @danwinship @caseydavenport

I've been pondering a bit more on the "how to enable default deny" case. From the Group posting we landed on:


We could add a "policyTypes" field indicating what kinds of traffic the 
policy affects. And if it's unspecified, it would get defaulted to: 

  - [ "ingress", "egress" ] if the policy has both ingress: and egress: 
    sections 

  - [ "egress" ] if the policy has an egress: section but no ingress: 
    section 

  - [ "ingress"] if the policy has an ingress: section but no egress: 
    section, or, for backward compatibility, if it has neither 
    ingress: nor egress:. 

Instead of adding something to NetworkPolicySpec, should we augment the Egress rule with a field that resembles the default? Then we can consider deprecating the current Ingress defaults over a few releases in favor of a similar change.

Ex:

// NetworkPolicyEgressRule describes a particular set of traffic that pods can egress to
// matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to.
type NetworkPolicyEgressRule struct {
	// List of destination ports for outgoing traffic.
	//Each item in this list is combined using a logical OR. If this field is
	// empty or missing, this rule matches all ports (traffic not restricted by port).
	// If this field is present and contains at least one item, then this rule does note
	// constrain outgoing traffic.
	// +optional
	Ports []NetworkPolicyPort

	// List of sources for outgoing traffic of pods selected for this rule.
	// Items in this list are combined using a logical OR operation. If this field is
	// empty or missing, this rule matches all sources (traffic not restricted by
	// source). If this field is present and contains at least on item, this rule
	// allows traffic only if the traffic matches at least one item in the from list.
	// +optional
	To []NetworkPolicyPeer

        // This is the default EgressRule applied to pods across a cluster.
        // Options are Permit or Prohibit
        // +optional
        DefaultPolicy: 
}

@danwinship
Copy link
Contributor

We can't have "DefaultPolicy" in NetworkPolicyEgressRule, because what if there were two rules with opposite default policies?

But maybe there could be something like a "Nothing" option in NetworkPolicyEgressRule/NetworkPolicyIngressRule so you can explicitly write a rule that doesn't match anything:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: default-deny-egress
spec:
  podSelector:
  egress:
  - to:
    - nothing:

and that combines fine with other policies without contradiction.

Although "Nothing" probably isn't the right name, and it can't be just an empty field because that would get lost in serialization.

@cmluciano
Copy link
Author

/retest

@cmluciano
Copy link
Author

I like the option of adding to the Peer group, however I'm also lost on what to name it.

@ahmetb
Copy link
Member

ahmetb commented Aug 28, 2017

Is there a design/proposal doc for egress rules in networkpolicy? Or is the comment #51351 (comment) sufficient enough to capture the gist of this work?

@cmluciano
Copy link
Author

@ahmetb The summary of proposals is in a google doc.

SIG-Network Mailing List Post: egress network policy requirements

@danwinship
Copy link
Contributor

So actually, wait, the problem is not "how to enable default deny", it's "how to not (accidentally) enable default deny". We told people to use a policy like this for ingress default-deny in 1.7:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
spec:
  podSelector:

But that will now implicitly have an empty egress rule array. So the solution has to be that, at least in some cases, an empty/non-existent egress section does not mean "deny all egress".

My suggestion had been to fix that by adding a way to specify that egress is ignored for a given policy (and make that the default behavior for existing policies).

I guess the other way would be to say that empty/non-existent egress never means "deny all egress", it means "allow all egress" (and you have to include an explicit don't-allow-anything NetworkPolicyEgressRule if you want to deny-all). But that's pretty egregiously different from ingress behavior.

@cmluciano
Copy link
Author

I'm fine with the PolicyType field for now if we want to maintain the Ingress behavior. I figured it was worth bringing up since the Default code that I started writing looked messy due to all of the edge-cases.

@@ -77,6 +86,26 @@ type NetworkPolicyIngressRule struct {
From []NetworkPolicyPeer
}

// NetworkPolicyEgressRule describes a particular set of traffic that is allowed out of pods
// matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small nit: The traffic must match both Ports and To

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cmluciano this comment is still pending it looks like

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JSON names are correct

// source). If this field is present and contains at least on item, this rule
// allows traffic only if the traffic matches at least one item in the from list.
// +optional
To []NetworkPolicyPeer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the to list. -> in the To list.

@aanm
Copy link
Contributor

aanm commented Aug 29, 2017

This egress policy is enforced on connections made from the pod but what about on reply packets?

Example:

  • an ingress policy for app=database to receive requests from app=frontend
  • an egress policy for app=database that is only allowed to send traffic to the app=backup

Based on the egress policy installed, can app=database reply to app=frontend?

@thockin
Copy link
Member

thockin commented Aug 29, 2017

We can't really deprecate the ingress defaults until we rev the API to v2{alpha,beta,}. It is part of the API semantic. Unfortunately, lack of ingress means no ingress, but we don't want lack of egress to mean no egress (that would be a breaking change). We should have demanded ingress be specified to mean "no ingress". We botched that. The policyTypes field is the remedy.

We might be able to slightly rectify the situation, though. I'm going to think out loud:

We have IPBlock now, which can unambiguously indicate "nothing" as 0.0.0.0/32 What if we:

  1. change the defaulting logic for NetworkPolicySpec to something like:
if len(spec.Ingress) == 0 {
  nothing := new(IPBlock)
  nothing.CIDR = "0.0.0.0/32"
  spec.Ingress = []NetworkPolicyIngressRule{{From: []NetworkPolicyPeer{{IPBlock: nothing}}}}
}
  1. add egress, demand that "deny all" specify to: { ipblock: { cidr: "0.0.0.0/32" }}

  2. change the above default logic to if len(spec.Ingress) + len(spec.Egress) == 0 {

If user specifies nothing, they get the default (no ingress).

If the user specifies ingress but not egress, they get their ingress rules

If the user specifies egress but not ingress, they get their egress rules

If the use specifies ingress and egress, they get their ingress and egress rules

The only thing that is irregular is the defaulting logic. Does this break anything? I am trying to work through it. If a user creates this on v1.8, then rolls back to v1.7, the ipBlock will get dropped, leaving an empty from which fails validation. Damn. We could change the validation in v1.8 and do the above in v1.9.


Starting over:

We could just leave the empty ingress to be irregular. Can we only make it irregular iff egress is not specified?

If the user specifies nothing, they get today's behavior (no ingress).

If the user specifies ingress but not egress, they get their ingress rules

If the user specifies egress but not ingress, they get their egress rules and ingress is unaffected

If the use specifies ingress and egress, they get their ingress and egress rules

Would this break anything? If a user had an empty NetworkPolicy object, and they add egress to it, it would stop being a no-ingress rule. That's bad.


Starting over:

What if we change the defaulting for NetworkPolicyPeer and allow all-nil to mean "none". That would be a breaking change upon rollback.


Starting over:

We're stuck. We can't even do what Dan suggested. I think we have to respect that any NP object that has no ingress block means "default-deny ingress". That means the policyTypes list has to always default to containing "Ingress". The only way it can not affect ingress is if the user specifies just "Egress".

Someone check my math or convince me I am wrong?

@danwinship
Copy link
Contributor

This egress policy is enforced on connections made from the pod but what about on reply packets?

Reply packets are always allowed, just like with ingress policy. (ie, if you have an ingress policy for app=database to receive requests from app=frontend, then that also allows replies from the database pod to the frontend pod, even though it doesn't allow the database pod to initiate connections to the frontend pod.)

@danwinship
Copy link
Contributor

We're stuck. We can't even do what Dan suggested. I think we have to respect that any NP object that has no ingress block means "default-deny ingress". That means the policyTypes list has to always default to containing "Ingress". The only way it can not affect ingress is if the user specifies just "Egress".

Someone check my math or convince me I am wrong?

Didn't you just contradict yourself? "any NP object that has no ingress block means 'default-deny ingress'" vs "The only way it can not affect ingress is if the user specifies just 'Egress'" ?

So like:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
spec:
  policyTypes: [ "Egress" ]
  egress:

Does that default-deny ingress or not?

If the concern is only with rollback, then it seems a little weird to worry about the ingress behavior of that policy after rolling back from 1.8 to 1.7, since regardless of the interpretation of ingress, the policy as a whole is guaranteed to not have the behavior the user wanted anyway...

If we need to make it possible to roll back and not have egress-only policies turn into deny-ingress policies then I guess the only way we can do that is to say that there's no such thing as an egress-only policy. So the fully foward-and-backward-compatible rule would be:

  • Any pod that is selected by any NetworkPolicy is deny-ingress, and only allows incoming connections that match the ingress clause of some NetworkPolicy that selects it. (Unchanged from 1.7; for rollback compatibility we have to ensure that any policy in 1.8 still has the same ingress semantics it would have had in 1.7 if you remove any new fields.)

  • Any pod that is selected by a NetworkPolicy that contains an egress clause is deny-egress, and only allows outgoing connections that match the egress clause of some NetworkPolicy that selects it. (For forward compatibility with existing 1.7 policies, we can't have egress be affected by policies that don't explicitly mention egress.)

  • To make an egress default-deny policy, you can do:

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    spec:
      podSelector:
      egress:
      - ipBlock:
          cidr: 0.0.0.0/0
    

    except that that's also a default-deny ingress policy too; there's no way to write a policy that just denies egress without affecting ingress. Which is terrible.

Actually, there's another way around the problem, which is if we say that podSelector only describes the pods affected by the ingress clause, and have a separate egressPodSelector to describe the pods that are affected by the egress section of the policy. And then you could write:

spec:
    egressPodSelector:
      matchLabels:
        app: frontend
    egress:    # empty == denied
    podSelector:
      matchLabels:
        asdfasdfasdfa: asdfasdfasdfasdfasdfas

or if you want to be more paranoid/explicit:

    podSelector:
      matchExpressions:
      - { key: dummy, operator: Exists }
      - { key: dummy, operator: NotExists }

either of which is also terrible, but maybe someone can come up with a less terrible version? (Or maybe we just let v1 be terrible but plan to move to a less-terrible v2 soon?)

@k8s-ci-robot k8s-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Aug 29, 2017
@cmluciano
Copy link
Author

@danwinship @thockin @caseydavenport Take a look at f058d5d . The tests will probably fail since I have not added this to v1beta1, but I wanted to see if this behavior works.

@thockin
Copy link
Member

thockin commented Aug 29, 2017

Didn't you just contradict yourself? "any NP object that has no ingress block means 'default-deny ingress'" vs "The only way it can not affect ingress is if the user specifies just 'Egress'" ?

I don't think so. I just wasn't clear. If policyTypes is explicitly [ "Egress" ] and nothing else, then the ingress block has no effect. If the policyTypes field is not specified, it MUST be defaulted to at least [ "Ingress" ], though I think it is safe to detect non-empty egress block and add "Egress" to policyTypes.

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
spec:
  policyTypes: [ "Egress" ]
  egress:

Does that default-deny ingress or not?

It would have no effect on Ingress. But you're right - upon a rollback, this breaks the cluster. Both policyTypes and egress would be ignored in 1.7, converting it to a default-deny ingress rule.

for rollback compatibility we have to ensure that any policy in 1.8 still has the same ingress semantics it would have had in 1.7 if you remove any new fields.

This is something I think I never really considered about one-of blocks. You can't add a new option and then allow rollbacks. Any IPBlock user who rolls back to 1.7 will be left with an object that fails validation. The NetworkPolicy "foobar2" is invalid: spec.ingress[0].from[0]: Required value: must specify a from type. We've already introduced a breaking change by adding IPBlock at all.

I need to think about how we do this elsewhere. It may be that we're setting the bar too high here.

@cmluciano
Copy link
Author

@thockin @danwinship @caseydavenport

This should pass all tests now.

TODO:

  • Need to validate empty policyTypes
  • Duplicate types
  • Refactor validation pieces (split out ports)

Can we have these as TODOs post-freeze?

@caseydavenport
Copy link
Member

caseydavenport commented Sep 1, 2017

I suspect we can make the validation tweaks post-freeze if we really need to.

I'd like to get a conclusion on this comment though: https://github.com/kubernetes/kubernetes/pull/51351/files#r136650232

@thockin @danwinship

Copy link
Member

@thockin thockin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly nits or code layout, not semantics.

@@ -133,4 +133,14 @@ func SetDefaults_NetworkPolicy(obj *extensionsv1beta1.NetworkPolicy) {
}
}
}

if obj.Spec.PolicyTypes == nil || len(obj.Spec.PolicyTypes) == 0 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, fixup in followup OK


if obj.Spec.PolicyTypes == nil || len(obj.Spec.PolicyTypes) == 0 {
// Default for undefined PolicyTypes with defined Egress rules
if obj.Spec.Egress != nil || len(obj.Spec.Egress) != 0 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same, just len()

if obj.Spec.PolicyTypes == nil || len(obj.Spec.PolicyTypes) == 0 {
// Default for undefined PolicyTypes with defined Egress rules
if obj.Spec.Egress != nil || len(obj.Spec.Egress) != 0 {
obj.Spec.PolicyTypes = []extensionsv1beta1.PolicyType{extensionsv1beta1.PolicyTypeIngress, extensionsv1beta1.PolicyTypeEgress}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes. I would restructure it as:

if len(obj.Spec.PolicyTypes) == 0 {
    // Any policy that does not specify policyTypes implies at least "Ingress".
    obj.Spec.PolicyTypes = []extensionsv1beta1.PolicyType{extensionsv1beta1.PolicyTypeIngress}
    if len(obj.Spec.Egress) != 0 {
        obj.Spec.PolicyTypes = append(obj.Spec.PolicyTypes, extensionsv1beta1.PolicyTypeEgress)
    }
}

// allowed if there are no NetworkPolicies selecting the pod (and cluster policy
// otherwise allows the traffic), OR if the traffic matches at least one egress rule
// across all of the NetworkPolicy objects whose podSelector matches the pod. If
// this field is empty then this NetworkPolicy does not limit any outgoing traffic.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we agree that empty hear means allow-all while empty ingress means deny-all? I can't recall why? It should be the same or well-documented here, why not.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we did - this should be the same as for ingress.

// (whether or not they contain an Ingress section) are assumed to affect Ingress.
// If you want to write an egress-only policy, you must explicitly specify PolicyTypes [ "Egress" ].
// Likewise, if you want to write a policy that specifies that no egress is allowed,
// you must specify a PolicyTypes values that include "Egress" (since such a policy would not include
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/values/value

s/PolicyType/policyType - JSON name

@@ -77,6 +86,26 @@ type NetworkPolicyIngressRule struct {
From []NetworkPolicyPeer
}

// NetworkPolicyEgressRule describes a particular set of traffic that is allowed out of pods
// matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JSON names are correct

if obj.Spec.PolicyTypes == nil || len(obj.Spec.PolicyTypes) == 0 {
// Default for undefined PolicyTypes with defined Egress rules
if obj.Spec.Egress != nil || len(obj.Spec.Egress) != 0 {
obj.Spec.PolicyTypes = []extensionsv1beta1.PolicyType{extensionsv1beta1.PolicyTypeIngress, extensionsv1beta1.PolicyTypeEgress}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@caseydavenport If we don't assume Ingress, then any policy that is a default-deny-ingress today would change meaning by adding an egress block. That's not compatible.

}
}
// Validate PolicyTypes
if len(spec.PolicyTypes) > 2 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not convert it to a sets.String, and check that the set only contains known items? I don't like coding in numbers like 2.

for i, pType := range spec.PolicyTypes {
policyPath := fldPath.Child("policyTypes").Index(i)
if pType != networking.PolicyTypeIngress && pType != networking.PolicyTypeEgress {
allErrs = append(allErrs, field.NotSupported(policyPath, pType, []string{string("Ingress"), string("Egress")}))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should use teh const values.

allowed := sets.NewString(PolicyTypeIngress, PolicyTypeEgress)
for _, p := range spec.PolicyTypes {
    if !allowed.Has(string(p)) {
        // error

@thockin
Copy link
Member

thockin commented Sep 1, 2017

/lgtm
/approve

http://gph.is/1y9uxL8

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Sep 1, 2017
@k8s-github-robot k8s-github-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Sep 1, 2017
@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

3 similar comments
@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

@k8s-github-robot k8s-github-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 3, 2017
Christopher M. Luciano added 3 commits September 5, 2017 12:01
Signed-off-by: Christopher M. Luciano <cmluciano@us.ibm.com>
Signed-off-by: Christopher M. Luciano <cmluciano@us.ibm.com>
@k8s-github-robot k8s-github-robot removed lgtm "Looks good to me", indicates that a PR is ready to be merged. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. labels Sep 5, 2017
@cmluciano
Copy link
Author

Since I needed to rebase and fix some golint stuff, I added the comment and validation suggestions as well. Will need another LGTM

@cmluciano
Copy link
Author

/test pull-kubernetes-unit

@thockin
Copy link
Member

thockin commented Sep 6, 2017

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Sep 6, 2017
@k8s-github-robot
Copy link

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: cmluciano, thockin

Associated issue: 50453

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these OWNERS Files:

You can indicate your approval by writing /approve in a comment
You can cancel your approval by writing /approve cancel in a comment

@caseydavenport
Copy link
Member

/test pull-kubernetes-e2e-kops-aws

@k8s-ci-robot
Copy link
Contributor

@cmluciano: The following test failed, say /retest to rerun them all:

Test name Commit Details Rerun command
pull-kubernetes-e2e-kops-aws 84290ce link /test pull-kubernetes-e2e-kops-aws

Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

@k8s-github-robot
Copy link

Automatic merge from submit-queue (batch tested with PRs 51984, 51351, 51873, 51795, 51634)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API lgtm "Looks good to me", indicates that a PR is ready to be merged. release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/network Categorizes an issue or PR as relevant to SIG Network. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

NetworkPolicy Egress with CIDRSelector and DNSSelector